import { ReactNode, useState } from 'react';
import { Button, message, Tree } from 'antd';
import an58 from '@mmstudio/an000058';
import router from 'next/router';
import RightContainer from '../../../components/rightcontainer';
import Title from './title';
import api from '../../../atoms/api';
import Add from './add';
import { Message as M1, Result as R1 } from '../../api/admin/menu/query.api';
import { Message as M2, Result as R2 } from '../../api/admin/menu/del.api';
import IconButton from '../../../components/iconbutton';
import Edit from './edit';
import confirm from '../../../atoms/confirm';

export interface ITreeData {
	title: string;
	key: string;
	checked?: boolean;
	isLeaf?: boolean;
	icon?: ReactNode;
	children?: ITreeData[];
}

export interface ITbfdmenuTree extends ITbfdmenu {
	children?: ITbfdmenuTree[];
}

export function d2n(data: ITbfdmenuTree): ITreeData {
	const icon = data.icon && <IconButton img={data.icon} />;
	const children = data.children?.map(d2n);
	return {
		title: data.name,
		key: data.menuid,
		icon,
		isLeaf: children && children.length === 0,
		children
	};
}

function treenode(node: ITbfdmenuTree, data: ITbfdmenu[]) {
	if (!node.children) {
		node.children = data.filter((it) => {
			return it.pid === node.menuid;
		}).map((it) => {
			return treenode(it, data);
		});
	}
	return node;
}

export function tree(data: ITbfdmenu[]) {
	return data.filter((it) => {
		return !it.pid;
	}).map((it) => {
		return treenode(it, data);
	});
}

function maptree(data: ITbfdmenuTree[]) {
	return data.reduce((pre, cur) => {
		const children = maptree(cur.children || []);
		children.forEach((v, k) => {
			pre.set(k, v);
		});
		return pre.set(cur.menuid, cur);
	}, new Map<string, ITbfdmenuTree>());
}

export default function Content({ initialdata }: {
	initialdata: ITbfdmenu[];
}) {
	const treenodes = tree(initialdata);
	const [data, setdata] = useState<ITreeData[]>(treenodes.map(d2n));
	const [alldata, setalldata] = useState(maptree(treenodes));
	// const [allnodes, setallnodes] = useState(data.reduce((pre, it) => {
	// 	return pre.set(it.key, it);
	// }, new Map<string, ITreeData>()));
	const [current, setcurrent] = useState(null as ITbfdmenuTree);
	function update(list: ITreeData[], cur: ITreeData): ITreeData[] {
		return list.map((node) => {
			if (node.key === cur.key) {
				return {
					...cur
				};
			}
			if (node.children) {
				return {
					...node,
					children: update(node.children, cur),
				};
			}
			return node;
		});
	}

	return <>
		<Title />
		<RightContainer>
			<Add pid={current && current.menuid} pname={current && current.name} onSave={(v) => {
				current.children.push(v);
				setcurrent(current);
				const cur = d2n(current);
				setdata((origin) => {
					return update(origin, cur);
				});
				setalldata((origin) => {
					return origin.set(v.menuid, v);
				});
			}} />
			<Button disabled={!current} danger type='primary' onClick={async () => {
				const ok = await confirm('删除', '确认删除');
				if (ok) {
					const res = await an58<R2, M2>(api['/api/admin/menu/del'], 'delete', {
						menuid: current.menuid
					});
					if (res.ok === true) {
						router.reload();
					} else {
						message.error(res.message);
					}
				}
			}}>删除</Button>
		</RightContainer>
		<div className='content'>
			<div className='form'>
				<Tree
					showIcon
					multiple={false}
					checkable={false}
					defaultExpandAll
					// loadData={async (node) => {
					// 	if (node.children || node.isLeaf) {
					// 		return;
					// 	}
					// 	const menuid = node.key as string;
					// 	const d = await an58<R1, M1>(api['/api/admin/menu/query'], 'get', {
					// 		pid: menuid
					// 	});
					// 	setalldata((origin) => {
					// 		return d.reduce((pre, cur) => {
					// 			return pre.set(cur.menuid, cur);
					// 		}, origin);
					// 	});
					// 	const data = d.map(d2n);
					// 	setallnodes((origin) => {
					// 		return data.reduce((pre, cur) => {
					// 			return pre.set(cur.key, cur);
					// 		}, origin);
					// 	});
					// 	const cur = allnodes.get(menuid);
					// 	cur.children = data;
					// 	if (data.length === 0) {
					// 		cur.isLeaf = true;
					// 	}
					// 	setdata((origin) => {
					// 		return update(origin, cur);
					// 	});
					// }}
					onSelect={(select) => {
						if (select.length > 0) {
							const cur = alldata.get(select[0] as string);
							setcurrent(cur);
						} else {
							setcurrent(null);
						}
					}}
					treeData={data}
				/>
			</div>
			<div className='form'>
				<Edit
					data={current}
					onSave={(v) => {
						setcurrent(v);
						const cur = d2n(v);
						// allnodes.set(v.menuid, cur);
						setdata((origin) => {
							return update(origin, cur);
						});
						setalldata((origin) => {
							return origin.set(v.menuid, v);
						});
					}}

					onChange={(k: keyof M1, v: string | number) => {
						setcurrent((origin) => {
							return {
								...origin,
								[k]: v
							} as ITbfdmenu;
						});
					}}
				/>
			</div>
		</div>
		<style jsx>{`
.content{
display: flex;
flex-direction: row;
justify-content: space-between;
}
.form{
	width: 50%;
	padding: 1vmax;
}
`}</style>
	</>;
}
